﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;

namespace Dapper_Core.DAL.Impl
{
    public class ReadSQLXml
    {

        public static Dictionary<string, XmlNode> XMLDic = new Dictionary<string, XmlNode>();

        /// <summary>
        /// 初始化SQLMAP
        /// </summary>
        public static void Init(bool web = true)
        {

            string sqlFile = string.Format("{0}\\Dapper_Core.DAL.Impl.dll", AppContext.BaseDirectory);
            //单元测试地址
            if (!web)
            {
                sqlFile = string.Format("{0}\\Dapper_Core.DAL.Impl.dll", AppContext.BaseDirectory);
            }
            Assembly asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(sqlFile);
            var MapArr = asm.GetManifestResourceNames();
            //Dapper_Core.DAL.Impl.Map
            foreach (var item in MapArr)
            {
                if (item.IndexOf("Dapper_Core.DAL.Impl.Map") == 0)
                {
                    ReadResourceFile(asm, item);
                }
            }
        }
        /// <summary>
        /// 将Map数据读取到内存中
        /// </summary>
        public static void ReadResourceFile(Assembly asm, string fileName)
        {Stream sm = asm.GetManifestResourceStream(fileName);
            XmlDocument xd = new XmlDocument();
            xd.Load(sm);
            foreach (XmlNode item in xd.ChildNodes[1].ChildNodes)
            {
                if (item.Attributes == null)
                {
                    continue;
                }
                var idObj = item.Attributes["id"];
                if (idObj != null)
                {
                    XMLDic.Add(idObj.Value, item);
                }

            }
            sm.Dispose();
        }

        #region 读取XML函数
        /// <summary>
        /// 创建SQL,刘中毅，2014.3.5 
        /// </summary>
        /// <returns></returns>
        public static string CreatSqlParaSql(string IdStr, Dictionary<string, string> parars, ref List<string> SqlParaList)
        {
            string SqlStr = null;
            SqlStr = NewReadXmlSql(IdStr, parars);
            SqlParaList = new List<string>();
            string Pattern = "#(.*?)#";
            Match m = Regex.Match(SqlStr, Pattern);
            while (m.Success)
            {
                string ParaStr = m.Groups[0].ToString().Trim('#');
                SqlParaList.Add(ParaStr);
                m = m.NextMatch();
            }
            Dictionary<string, string>.Enumerator emList = parars.GetEnumerator();
            while (emList.MoveNext())
            {
                string tempStr = emList.Current.Key;
                string tempValue = string.IsNullOrWhiteSpace(emList.Current.Value) ? "" : emList.Current.Value.ToString();
                SqlStr = SqlStr.Replace("'#" + tempStr + "#'", "@" + tempStr);
                SqlStr = SqlStr.Replace("#" + tempStr + "#", "@" + tempStr);
                SqlStr = SqlStr.Replace("$" + tempStr + "$", tempValue);
            }
            return SqlStr;
        }
        /// <summary>
        ///  读取XML文档的语句，动态拼接
        /// </summary>
        /// <param name="dotype"></param>
        /// <param name="idstr"></param>
        /// <param name="parars"></param>
        /// <returns></returns>
        public static string NewReadXmlSql(string idstr, Dictionary<string, string> parars)
        {
            string sql = "";
            if (string.IsNullOrWhiteSpace(idstr))
            {
                return "";
            }
            sql = FooXnodes(XMLDic[idstr], parars);
            return sql;
        }

        /// <summary>
        /// 递归读取XML文档
        /// </summary>
        /// <param name="nodes"></param>
        /// <param name="parars"></param>
        /// <returns></returns>
        public static string FooXnodes(XmlNode nodes, Dictionary<string, string> parars)
        {
            StringBuilder sql = new StringBuilder();
            if (nodes.HasChildNodes)
            {
                foreach (XmlNode item in nodes.ChildNodes)
                {
                    switch (item.Name)
                    {
                        case "dynamic":
                            string dynamicProperty = "";
                            if (item.Attributes.Count > 0 && item.Attributes["prepend"] != null)
                            {
                                dynamicProperty = item.Attributes["prepend"].Value;
                            }
                            string dymStr = FooXnodes(item, parars);
                            if (string.IsNullOrWhiteSpace(dynamicProperty) && (!string.IsNullOrWhiteSpace(dymStr)) && dymStr.Trim().Length > 0)
                            {
                                sql.Append(dymStr);
                            }
                            else
                            {
                                if ((!string.IsNullOrWhiteSpace(dymStr)) && dymStr.Trim().Length > 0)
                                {
                                    sql.Append(dynamicProperty + dymStr);
                                }
                            }
                            break;
                        case "isNotEmpty":
                            string key = item.Attributes["property"].Value;
                            if (parars.ContainsKey(key) && (!string.IsNullOrWhiteSpace(parars[key])))
                            {
                                //有一个子级并且子级是Text类型那么直接就获取结果,否者再次遍历子级
                                if (item.HasChildNodes && item.ChildNodes.Count == 1 && item.ChildNodes[0].NodeType == XmlNodeType.Text)
                                {
                                    sql.Append(item.ChildNodes[0].Value);
                                }
                                else
                                {
                                    sql.Append(FooXnodes(item, parars));
                                }
                            }
                            break;
                        case "isEqual":
                            string equal_key = item.Attributes["property"].Value;
                            string compareValue = item.Attributes["compareValue"].Value;
                            if (parars.ContainsKey(equal_key) && (!string.IsNullOrWhiteSpace(parars[equal_key])) && compareValue.Equals(parars[equal_key]))
                            {
                                if (item.HasChildNodes && item.ChildNodes.Count == 1 && item.ChildNodes[0].NodeType == XmlNodeType.Text)
                                {
                                    sql.Append(item.ChildNodes[0].Value);
                                }
                                else
                                {
                                    sql.Append(FooXnodes(item, parars));
                                }
                            }
                            break;
                        default:
                            switch (item.NodeType)
                            {
                                case XmlNodeType.Text:
                                    sql.Append(item.HasChildNodes ? "" : item.Value);
                                    break;
                                case XmlNodeType.CDATA:
                                    sql.Append(item.Value);
                                    break;
                            }
                            break;
                    }
                }
            }
            else
            {
                sql.Append(nodes.Value);
            }
            //按照关键词解析
            return sql.ToString();
        }

        #endregion
    }
}
